﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;



namespace AudiPyme.DAL
{
    public class AnalisisRiesgoFactory
    {
        //Inserta los elementos de Análisis de Riesgo en los informes
        public static void InsertaAnalisisRiesgo(int IdActivo, int Riesgo, int IdAmenaza, int IdControl, int IdInforme)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            //Una nueva instancia Análisis de Riesgo por cada tupla (Activo,Amenaza,Control) distinta
            AnalisisRiesgo nuevoAR = new AnalisisRiesgo();
            nuevoAR.IdActivo = IdActivo;
            nuevoAR.Riesgo = Riesgo;
            nuevoAR.IdAmenaza = IdAmenaza;
            nuevoAR.IdControl = IdControl;
            nuevoAR.IdInforme = IdInforme;
            agenteBD.AddToAnalisisRiesgoEstablecer(nuevoAR);
            agenteBD.SaveChanges();
        }

        //Devuelve toda la estructura del Análisis de Riesgo de un Informe
        public static List<AnalisisRiesgo> AnalisisRiesgoEmpresa(int IdInforme)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<AnalisisRiesgo> LAnalisis = from AR in agenteBD.AnalisisRiesgoEstablecer
                                                   join Inf in agenteBD.InformesEstablecer on AR.IdInforme equals Inf.IdInforme
                                                   where Inf.IdInforme == IdInforme
                                                   orderby AR.Riesgo, AR.IdActivo, AR.IdAmenaza, AR.IdControl
                                                   select AR;
            if (LAnalisis.Count() == 0)
            {
                return new List<AnalisisRiesgo>();
            }
            else
            {
                return LAnalisis.ToList();
            }
        }

        //Método que recoge el último Id de Informe de una Empresa
        public static int UltimoIdInformeEmpresa(int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            List<int> LIdsInformeEmpresa = ((from Inf in agenteBD.InformesEstablecer
                                             join ActInf in agenteBD.ActivosInformeEstablecer on Inf.IdInforme equals ActInf.IdInforme
                                             join ActEmp in agenteBD.ActivosEmpresaEstablecer on ActInf.IdActivo equals ActEmp.IdActivo
                                             where ActEmp.IdEmpresa == IdEmpresa
                                             select Inf.IdInforme).Distinct()).ToList();
            LIdsInformeEmpresa.Sort();
            return LIdsInformeEmpresa.Last();
        }

        //Método que elimina de forma permanente, todos los anális de riesgos, asociados a una empresa
        internal static void EliminaTotalAnalisisRiesgo(int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<AnalisisRiesgo> AnalisisRiesgoQuery = from AnaRies in agenteBD.AnalisisRiesgoEstablecer
                                                             join EmpInf in agenteBD.EmpresaInformeEstablecer on AnaRies.IdInforme equals EmpInf.IdInforme
                                                             where EmpInf.IdEmpresa == IdEmpresa
                                                             select AnaRies;
            if (AnalisisRiesgoQuery.Count() != 0)
            {
                foreach (AnalisisRiesgo AR in AnalisisRiesgoQuery)
                {
                    agenteBD.AnalisisRiesgoEstablecer.DeleteObject(AR);
                }
                agenteBD.SaveChanges();
            }
        }

        //Método que elimina de forma permanente, todos los anális de riesgos, asociados a un Informe
        internal static void EliminaAnalisisRiesgoInforme(int IdInforme)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<AnalisisRiesgo> AnalisisRiesgoQuery = from AnaRies in agenteBD.AnalisisRiesgoEstablecer
                                                             where AnaRies.IdInforme == IdInforme
                                                             select AnaRies;
            if (AnalisisRiesgoQuery.Count() != 0)
            {
                foreach (AnalisisRiesgo AR in AnalisisRiesgoQuery)
                {
                    agenteBD.AnalisisRiesgoEstablecer.DeleteObject(AR);
                }
                agenteBD.SaveChanges();
            }
        }

        //Método que elimina todos los elementos de análisis de riesgos asociados a una lista de informes
        internal static void EliminaAnalisisRiesgoInformes(List<int> LInformes)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<AnalisisRiesgo> AnalisisRiesgoQuery = from AnaRies in agenteBD.AnalisisRiesgoEstablecer
                                                             where LInformes.Contains(AnaRies.IdInforme)
                                                             select AnaRies;
            if (AnalisisRiesgoQuery.Count() != 0)
            {
                foreach (AnalisisRiesgo AR in AnalisisRiesgoQuery)
                {
                    agenteBD.AnalisisRiesgoEstablecer.DeleteObject(AR);
                }
                agenteBD.SaveChanges();
            }
        }

        //Devuelve el número de activos que están a un nivel de Riesgo Dado
        public static int NumeroActivosNivelRiesgo(int IdInforme, int NivelRiesgoActual)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            int NumeroActivos = (from AnRiesg in agenteBD.AnalisisRiesgoEstablecer
                                 where AnRiesg.IdInforme == IdInforme && AnRiesg.Riesgo == NivelRiesgoActual
                                 select AnRiesg.IdActivo).Distinct().Count();
            return NumeroActivos;
        }

        //Elemento que recoge la Amenaza que se repite más veces en la base de conocimiento con el Tipo de Activo
        //que hay en el elemento de RiesgoActivo ElementoPlanMejora. De esta forma, se elige la amenaza más propensa
        //a manifestarse según la base de datos de conocimiento
        public static int IdAmenazaMaxima(int IdActivo, int IdInforme, int NivelMaximoRiesgoActivo)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            var AmenazasTipoActivo = (from ar in agenteBD.AnalisisRiesgoEstablecer
                                      where ar.IdActivo == IdActivo && ar.IdInforme == IdInforme && ar.Riesgo == NivelMaximoRiesgoActivo
                                      select new { ar.IdActivo, ar.IdAmenaza }).OrderBy(t => t.IdActivo).ThenBy(a => a.IdAmenaza);
            var AgrupadosAmenazasTipoActivo = (from AmenTipAct in AmenazasTipoActivo
                                               group AmenTipAct by new { AmenTipAct.IdActivo, AmenTipAct.IdAmenaza } into grupo
                                               select new { grupo.Key.IdActivo, grupo.Key.IdAmenaza, Count = grupo.Count(f => f.IdAmenaza != null) }).OrderByDescending(d => d.Count);
            int IdAmenazaElegida = 0;
            int NumVecesAmenazaElegida = 0;
            foreach (var ElementoAmenazaTipoActivo in AgrupadosAmenazasTipoActivo)
            {
                if (ElementoAmenazaTipoActivo.Count > NumVecesAmenazaElegida)
                {
                    IdAmenazaElegida = ElementoAmenazaTipoActivo.IdAmenaza;
                    NumVecesAmenazaElegida = ElementoAmenazaTipoActivo.Count;
                }

            }
            return IdAmenazaElegida;

        }




    }
}
